package edu.ccut.saturn.studio.dialog;

import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.dialogs.AbstractElementListSelectionDialog;
import org.w3c.dom.Document;

import edu.ccut.saturn.studio.Activator;
import edu.ccut.saturn.studio.Images;
import edu.ccut.saturn.studio.core.util.eclipse.Messages;
import edu.ccut.saturn.studio.core.util.eclipse.SaturnSWTUtils;
import edu.ccut.saturn.studio.logic.model.Shape;
import edu.ccut.saturn.studio.util.ConversionUtil;

public class FilterDialog extends AbstractElementListSelectionDialog {

	protected Object[] fElements;

	private Object[] workspaceKey;

	private Shape shape;

	private String[] temp = new String[] { "" };

	private Map<String, Document> map;

	public FilterDialog(Shell parent, Shape shape) {
		super(parent, new SaturnSWTUtils.SaturnLabelDefaultProvider());
		this.shape = shape;
	}

	public FilterDialog(Shell parent, ILabelProvider renderer, Shape shape) {
		super(parent, renderer);
		this.shape = shape;
	}

	public void setElements(Object[] elements) {
		fElements = elements;
	}

	protected void computeResult() {
		setResult(Arrays.asList(getSelectedElements()));
	}

	protected Control createDialogArea(Composite parent) {
		Composite contents = (Composite) super.createDialogArea(parent);
		createSearch(contents);
		createFilterText(contents);
		createFilteredList(contents);
		createMessageArea(contents);
		if (fElements.length != 0) {
			setListElements(fElements);
		} else {
			setListElements(temp);
		}
		setSelection(getInitialElementSelections().toArray());

		return contents;
	}

	protected Text createJarPathText(Composite parent) {

		Text text = new Text(parent, SWT.BORDER | SWT.READ_ONLY);

		GridData data = new GridData();
		data.grabExcessVerticalSpace = false;
		data.grabExcessHorizontalSpace = true;
		data.horizontalAlignment = GridData.FILL;
		data.verticalAlignment = GridData.BEGINNING;
		text.setLayoutData(data);
		text.setFont(parent.getFont());

		return text;
	}

	private Composite createSearch(Composite parent) {

		MenuItem projectMenuItem;
		MenuItem AllMenuItem;

		final Composite composite = new Composite(parent, SWT.NONE);
		final GridData gd_composite = new GridData(SWT.FILL, SWT.FILL, true,
				false);
		gd_composite.heightHint = 28;
		composite.setLayoutData(gd_composite);
		composite.setLayout(new FormLayout());

		final Label label = new Label(composite, SWT.NONE);
		final FormData fd_label = new FormData();
		fd_label.bottom = new FormAttachment(0, 24);
		fd_label.top = new FormAttachment(16);
		fd_label.right = new FormAttachment(0, 27);
		fd_label.left = new FormAttachment(0, 2);
		label.setLayoutData(fd_label);
		label.setText(Messages.getString("FilterDialog.KeyValue")); //$NON-NLS-1$

		final ToolBar toolBar = new ToolBar(composite, SWT.FLAT);
		final FormData fd_toolBar = new FormData();
		fd_toolBar.top = new FormAttachment(0);
		fd_toolBar.right = new FormAttachment(100);
		toolBar.setLayoutData(fd_toolBar);
		final ToolItem projectToolItem = new ToolItem(toolBar, SWT.DROP_DOWN);
		projectToolItem.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent e) {
				if (e.detail == 0) {
					setListElements(fElements);
				}
			}
		});

		projectToolItem.setImage(Activator.getImage(Images.AMPLIFY_PLUS));
		final Menu menu = new Menu(toolBar);
		addDropDown(projectToolItem, menu);
		projectMenuItem = new MenuItem(menu, SWT.NONE);
		projectMenuItem.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent e) {
				setListElements(fElements);
			}
		});
		projectMenuItem.setText(Messages.getString("FilterDialog.SearchProject")); //$NON-NLS-1$
		AllMenuItem = new MenuItem(menu, SWT.NONE);
		AllMenuItem.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent e) {

				IRunnableWithProgress op = new IRunnableWithProgress() {
					public void run(IProgressMonitor monitor)
							throws InvocationTargetException {
						monitor.beginTask(
								Messages.getString("FilterDialog.Searching"), 100); //$NON-NLS-1$
						GUIUpdater g = new GUIUpdater(monitor);
						Thread t = new Thread(g);
						t.start();
						map = shape.keyMapInWorkspace();
						workspaceKey = ConversionUtil.conversion(map.keySet());

						String[] ss = new String[workspaceKey.length];
						
						for(int i=0; i < workspaceKey.length; i++){
							ss[i] = workspaceKey[i].toString();
							ss[i] = ss[i].substring(ss[i].indexOf("::")+2);
						}
						
						setListElements(dealarray(ss));
					}
				};
				try {
					new ProgressMonitorDialog(getShell()).run(true, false, op);
				} catch (Exception e1) {
				}

			}
		});
		AllMenuItem.setText(Messages.getString("FilterDialog.SearchWorkplace")); //$NON-NLS-1$
		return composite;
	}

	protected Object[] dealarray(Object[] array) {
		return array;
	}

	class GUIUpdater implements Runnable {
		private IProgressMonitor monitor;

		GUIUpdater(IProgressMonitor monitor) {
			this.monitor = monitor;
		}

		public void run() {
			for (int i = 0; i < 34; i++) {
				try {
					Thread.sleep(800);
					this.monitor.worked(3);
					if (workspaceKey != null) {
						this.monitor.worked(100);
						break;
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

	}

	private static void addDropDown(final ToolItem item, final Menu menu) {
		item.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event event) {
				if (event.detail == SWT.ARROW) {
					Rectangle rect = item.getBounds();
					Point pt = new Point(rect.x, rect.y + rect.height);
					pt = item.getParent().toDisplay(pt);
					menu.setLocation(pt.x, pt.y);
					menu.setVisible(true);
				}
			}
		});
	}

	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		newShell.setImage(Activator.getImage(Images.SATURN_ICONS_SMALLNAME));
	}

	public Map<String, Document> getMap() {
		return map;
	}

	public void setMap(Map<String, Document> map) {
		this.map = map;
	}
}
